package com.tian.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * 2023年06月20日 08:56
 * 博客地址：<a href="http://woaijava.cc/">博客地址</a>
 * <p>
 * 生成二维码
 */
@Slf4j
public class TwoDimensionalCodeGenerator {

    private static final String QR_CODE_IMAGE_PATH = "MyQRCode1.png";

    public static void main(String[] args) {
        String url = "http://vc8ku5.natappfree.cc/user/registerPage";
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("invitedCode", "22222");
        String twoDimensionalCode = getTwoDimensionalCode(url, paramMap);
        System.out.println(twoDimensionalCode);
    }

    /**
     * 生成二维码 two-dimensional code
     *
     * @param url      地址
     * @param paramMap 参数
     */
    public static String getTwoDimensionalCode(String url, Map<String, Object> paramMap) {
        // 要生成二维码的文本信息
        StringBuilder stringBuilder = new StringBuilder(url);
        stringBuilder.append("?");
        for (String s : paramMap.keySet()) {
            stringBuilder.append(s).append("=").append(paramMap.get(s)).append("&");
        }
        String text = stringBuilder.toString();
        if (text.endsWith("&")) {
            text = text.substring(0, text.length() - 1);
        }
        System.out.println("内容"+text);
        // 图片的宽度
        int width = 300;
        // 图片的高度
        int height = 300;
        // 图片的格式
        String format = "png";

        Map<EncodeHintType, Object> hints = new HashMap<>(8);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
        hints.put(EncodeHintType.MARGIN, 1);

        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);

            Path path = FileSystems.getDefault().getPath(QR_CODE_IMAGE_PATH);
            MatrixToImageWriter.writeToPath(bitMatrix, format, path);
            log.info("生成二维码地址:{}", QR_CODE_IMAGE_PATH);
            return QR_CODE_IMAGE_PATH;
        } catch (WriterException | IOException e) {
            log.error(e.getMessage());
        }
        return null;
    }

    public static class MatrixToImageWriter {

        private static final int BLACK = 0xFF000000;
        private static final int WHITE = 0xFFFFFFFF;

        private MatrixToImageWriter() {
        }

        public static BufferedImage toBufferedImage(BitMatrix matrix) {
            int width = matrix.getWidth();
            int height = matrix.getHeight();
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
                }
            }
            return image;
        }

        public static void writeToPath(BitMatrix matrix, String format, Path path) throws IOException {
            BufferedImage image = toBufferedImage(matrix);
            if (!ImageIO.write(image, format, path.toFile())) {
                throw new IOException("Could not write an image of format " + format + " to " + path);
            }
        }
    }

}
